package Jets.animate
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.FrameLabel;
	import flash.events.Event;
	import flash.utils.getDefinitionByName;
	
	import Jets.display.JSprite;
	import Jets.events.JAnimateEvent;
	import Jets.interfaces.InJAnimate;
	
	/**
	 * 动画的基类，不允许实例化
	 */
	public class JAnimateBase extends JSprite implements InJAnimate
	{
		private var ms_nFrameRate:Number = NaN;
		private var numLoops:int = -1;//循环次数，-1为无限循环
		private var nextLabels:Array = [];//Labels列表
		private var _queueDestory:Boolean = false;
		
		protected var ms_nLabelArr:Array;
		protected var ms_nCurrentFrame:int = 1;
		protected var ms_nTotalFrames:int = 1;
		protected var curLabelIndex:int = 0;//缓存LabelIndex的序号，避免重复遍历
		protected var frameTimer:int = 0;//记时器，小于0则需要播放，直到大于0
		/**
		 * 连接到自己的MovieClip对象
		 */
		protected var ms_nLinkAnimateArr:Array;
		
		/**
		 * 是否在动画结束后暂停 
		 */
		public var playOnce:Boolean = true;
		
		/**
		 * 设置相同的Label是否重置
		 */
		public var resetLabel:Boolean = true;
		
		/**
		 * 是否使用标签动画
		 */
		public var enabledLabelMovie:Boolean = true;
		private var ms_nContent:* = null;
		public function JAnimateBase(content:* = null,paused:Boolean=false)
		{
			super();
			if(content)
			{
				setContent(content);
			}
			this.TickEnable = true;
		}
		
		
		protected function setContent(value:*):void
		{
			var content:* = null
			if(value is String)
			{
				content = getDefinitionByName(value as String);
			}
			if(value is Class)
			{
				content = new value();
			}
			if(value == ms_nContent)
			{
				return;
			}
			if(value is BitmapData)
			{
				content = new Bitmap(value);
			}
			if(value is DisplayObject)
			{
				content = value;
			}
			if(content)
			{
				removeFromDisplay(this,ms_nContent);
				ms_nContent = content;
				this.addChild(ms_nContent);
			}
		}
		
		protected function getContent():Object
		{
			// TODO Auto Generated method stub
			return ms_nContent;
		}
		
		override protected function onAddStageEvent():void
		{
			super.onAddStageEvent();
			if(ms_nContent && !this.contains(ms_nContent))
			{
				this.addChild(ms_nContent);
			}
		}
		
		/**
		 * 设置帧频，设为NaN表示使用默认帧频，负值则为倒放。
		 */		
		public function get frameRate():Number
		{
			if (!isNaN(ms_nFrameRate))
			{
				return 	ms_nFrameRate;
			}
			else if (stage)
			{
				return stage.frameRate;
			}
			else
			{
				return NaN;
			}
		}
		
		public function set frameRate(v:Number):void
		{
			ms_nFrameRate = v;
		}
		
		/**
		 * 获得标签的序号
		 *  
		 * @param labelName
		 * @return 
		 * 
		 */
		public function getLabelIndex(labelName:String):int
		{
			var len:int = labels.length;
			for (var i:int = 0;i < len;i++)
			{
				if ((labels[i] as FrameLabel).name == labelName)
					return i;
			}
			return -1;
		}
		
		/**
		 * 是否存在某个标签
		 * 
		 * @param labelName
		 * @return 
		 * 
		 */
		public function hasLabel(labelName:String):Boolean
		{
			return getLabelIndex(labelName) != -1;
		}
		
		/**
		 * 设置循环次数 
		 * @param loop
		 * 
		 */
		public function setLoop(loop:int):void
		{
			this.numLoops = loop;
		}
		
		public function getLoop():int
		{
			return this.numLoops;
		}
		
		/**
		 * 设置当前动画 
		 * @param labelName		动画名称
		 * @param repeat		动画循环次数，设为-1为无限循环
		 * @param clearQueue	是否清除动画队列
		 */
		
		public function setLabel(labelName:String, repeat:int=-1, clearQueue:Boolean = true):void
		{
			if (clearQueue)
				this.clearQueue();
			
			var index:int = labelName ? getLabelIndex(labelName) : 0;
			
			if (index != -1)
			{
				numLoops = repeat;
				if (!resetLabel && index == curLabelIndex)
					return;
				
				currentFrame  = (frameRate < 0) ? getLabelEnd(index) : getLabelStart(index);
				curLabelIndex = index;
				
				var e:JAnimateEvent = new JAnimateEvent(JAnimateEvent.ANIMATE_START,labelName);
				dispatchEvent(e);
			}
			else
			{
				e = new JAnimateEvent(JAnimateEvent.ANIMATE_END,labelName);
				dispatchEvent(e);
				
				e = new JAnimateEvent(JAnimateEvent.ANIMATE_ERROR,labelName);
				dispatchEvent(e);
			}
		}
		
		/**
		 *
		 * 将动画推入列表，延迟播放
		 * @param labelName		动画名称
		 * @param repeat		动画循环次数，设为-1为无限循环
		 * 
		 */
		
		public function queueLabel(labelName:String, repeat:int=-1):void
		{
			nextLabels.push([labelName, repeat]);
		}
		
		/**
		 * 清除动画队列 
		 */
		
		public function clearQueue():void
		{
			nextLabels = [];
			_queueDestory = false;
		}
		
		/**
		 * 初始化动画
		 * 
		 */
		public function reset():void
		{
			setLabel(null);
		}
		
		protected override function onTickEvent(delay:Number):void
		{
			if (numLoops == 0 || totalFrames <= 1 || frameRate == 0)
				return;
			
			frameTimer -= delay;
			while (numLoops != 0 && frameTimer < 0) 
			{
				if (hasReachedLabelEnd())
				{
					if (numLoops > 0)
						numLoops--;
					
					if (numLoops == 0)
					{
						var e:JAnimateEvent = new JAnimateEvent(JAnimateEvent.ANIMATE_END,curLabelName);
						dispatchEvent(e);
						
						if (nextLabels.length > 0)
						{
							setLabel(nextLabels[0][0], nextLabels[0][1], false);
							nextLabels.splice(0, 1);
						}
						else 
						{
							e = new JAnimateEvent(JAnimateEvent.ANIMATE_EMPTY,curLabelName);
							dispatchEvent(e);
							
							if (_queueDestory)
								onRelease();
							
							frameTimer = 0;//停止动画时需要将延时重置为0
						}
					}
					else 
					{
						loopBackToStart();
					}
				}
				else
				{
					nextFrame()
				}
				
				frameTimer += 1000/ Math.abs(frameRate);
			}
		}
		
		/**
		 * 当前帧标签内的位置
		 * @return 
		 * 
		 */
		public function get frameInLabel():int
		{
			return currentFrame - getLabelStart(curLabelIndex) + 1;
		}
		
		public function set frameInLabel(v:int):void
		{
			currentFrame = getLabelStart(curLabelIndex) + v - 1;
		}
		
		/**
		 * 回到当前动画的第一帧（反向播放则是最后一帧）
		 */
		public function loopBackToStart():void
		{
			currentFrame = (frameRate < 0) ? getLabelEnd(curLabelIndex) : getLabelStart(curLabelIndex);
		}
		
		//检测是否已经到达当前区段的尾端（倒放则相反）
		private function hasReachedLabelEnd():Boolean
		{
			if (frameRate < 0)
				return currentFrame <= getLabelStart(curLabelIndex);
			else
				return currentFrame >= getLabelEnd(curLabelIndex);
		}
		
		//取得Label的头部
		private function getLabelStart(labelIndex:int):int
		{
			return (labels && labels.length > 0) ? labels[labelIndex].frame : 1;
		}
		
		//取得Label的尾端
		private function getLabelEnd(labelIndex:int):int
		{
			if (labels && labelIndex + 1 < labels.length)
				return labels[labelIndex + 1].frame - 1;
			else
				return totalFrames;
		}
		
		/** @inheritDoc*/
		override protected function onRelease(event:Event=null):void
		{
			super.onRelease();
		}
		
		/**
		 * 是否有帧标签 
		 * @return 
		 * 
		 */
		public function hasLabels():Boolean
		{
			return labels && labels.length > 0;
		}
		
		/**
		 * 所有标签，类型为FrameLabel
		 * @return 
		 * 
		 */
		public function get labels():Array
		{
			return enabledLabelMovie ? ms_nLabelArr : null;
		}
		
		public function set labels(value:Array):void
		{
			ms_nLabelArr = value;
		}
		
		/**
		 * 当前动画名称
		 * @return 
		 * 
		 */	
		public function get curLabelName():String
		{
			for (var i:int = labels.length - 1;i>=0;i--)
			{
				if ((labels[i] as FrameLabel).frame <= currentFrame)
					return (labels[i] as FrameLabel).name;
			}
			return null;
		}
		
		/**
		 * 当前帧
		 * 
		 * @return 
		 * 
		 */
		public function get currentFrame():int
		{
			return ms_nCurrentFrame;
		}
		
		public function set currentFrame(frame:int):void
		{
			ms_nCurrentFrame = frame;
			if (ms_nLinkAnimateArr)
			{
				for each (var mc:JAnimateBase in ms_nLinkAnimateArr)
				mc.currentFrame = frame;
			}
		}
		
		/**
		 * 总帧数
		 * 
		 * @return 
		 * 
		 */
		public function get totalFrames():int
		{
			return ms_nTotalFrames;
		}
		
		/**
		 * 下一帧（倒放时则是上一帧）
		 * 
		 */
		public function nextFrame():void
		{
			(frameRate < 0) ? currentFrame -- : currentFrame ++;
		}
		
		public function set linkAnimateArr(value:Array):void
		{
			ms_nLinkAnimateArr = value;
		}
		
		public function get linkAnimateArr():Array
		{
			return ms_nLinkAnimateArr
		}
		
		/**
		 * 连接到另一个动画，由目标动画控制自己的帧跳转
		 * @param target
		 * 
		 */
		public function linkTo(target:InJAnimate):void
		{
			if (!target.linkAnimateArr)
				target.linkAnimateArr = [];
			
			target.linkAnimateArr.push(this);
		}
		
		/**
		 * 解除动画连接 
		 * @param target
		 * 
		 */
		public function removeLinkFrom(target:InJAnimate):void
		{
			removeObj(target.linkAnimateArr,this);
			
			if (target.linkAnimateArr.length == 0)
				target.linkAnimateArr = null;
		}
		
		/**
		 * 播放动画后销毁自身
		 * 
		 */
		public function queueDestory():void
		{
			_queueDestory = true;
		}
		
		/**
		 * 从一个对象中删除一个值
		 * 
		 * @param obj	对象
		 * @param data	要删除的内容
		 * 
		 */		
		public static function removeObj(obj:*,data:*):void
		{
			var index:int;
			if (obj is Array)
			{
				index = (obj as Array).indexOf(data);
				if (index!=-1)
					(obj as Array).splice(index, 1);
			}
			else
			{
				for (var key:* in obj)
				{
					if (obj[key]==data)
					{
						delete obj[key];
						return;
					}
				}
			}
		}
	}
}